﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Exc5;

namespace CheckersUI
{
    public partial class UICheckersBoard : Form
    {
        private UICheckersCell[,] m_UIBoard;
        private CheckersMove m_currentMove;
        private string m_moveToInterpretate;
        private GameBoard m_GameBoard;
        private Player m_PlayerX;
        private Player m_PlayerO;
        private Player m_currentPlayer;
        private int m_numberOfPlayers;

        public UICheckersBoard(GameBoard i_GameBoard, Player i_PlayerX, Player i_PlayerO, int i_numberOfPlayers)
        {
            this.InitializeComponent();
            this.m_PlayerO = i_PlayerO;
            this.m_PlayerO.InitializePlayerPawnsArray(i_GameBoard.Size);
            this.m_PlayerX = i_PlayerX;
            this.m_PlayerX.InitializePlayerPawnsArray(i_GameBoard.Size);
            this.m_currentPlayer = this.m_PlayerO;
            this.m_GameBoard = i_GameBoard;
            this.m_GameBoard.CreateNewBoard(this.m_GameBoard.Size);
            this.m_GameBoard.initializeGameBoardWithPlayersPawns(this.m_PlayerO, this.m_PlayerX);
            this.InitializeBoard(this.m_GameBoard.Size, this.m_PlayerO, this.m_PlayerX);
            this.m_currentMove = new CheckersMove();
            this.m_moveToInterpretate = string.Empty;
            this.m_GameBoard.OnChangeCellStatus += this.UpdateUIBoardOnClick;
            CheckersGame.ThisIsTheEndOfTheMatch += this.HandleEndOfMatch;
            this.m_numberOfPlayers = i_numberOfPlayers;
            CheckersGame.CheckForAvailableMoves(ref this.m_PlayerO, this.m_GameBoard);
            CheckersGame.CheckForAvailableMoves(ref this.m_PlayerX, this.m_GameBoard);
        }

        private void InitializeBoard(int i_GameBoardSize, Player i_PlayerO, Player i_PlayerX)
        {
            this.m_UIBoard = new UICheckersCell[i_GameBoardSize, i_GameBoardSize];
            const int k_BottonSize = 40;

            labelPlayer1.Text = i_PlayerO.Name + ": " + i_PlayerO.Points;
            labelPlayer2.Text = i_PlayerX.Name + ": " + i_PlayerX.Points; 

            for (int i = 0; i < i_GameBoardSize; i++)
            {
                for (int j = 0; j < i_GameBoardSize; j++)
                {
                    this.m_UIBoard[i, j] = new UICheckersCell();
                    this.m_UIBoard[i, j].Location = new Point(15 + (k_BottonSize * i) + 3, 40 + (k_BottonSize * j) + 3);
                    this.m_UIBoard[i, j].Size = new Size(40, 40);
                    this.m_UIBoard[i, j].Column = (char)(i + 'A');
                    this.m_UIBoard[i, j].Row = (char)(j + 'a');
                    if (i % 2 == j % 2)
                    {
                        this.m_UIBoard[i, j].BackColor = Color.Gray;
                        this.m_UIBoard[i, j].Enabled = false;
                    }

                    this.m_UIBoard[i, j].OnButtonClick += this.WhenButtonClicked;
                    this.Controls.Add(this.m_UIBoard[i, j]);
                }
            }

            this.InitialPawnsDrawing(i_PlayerO);
            this.InitialPawnsDrawing(i_PlayerX);
        }

        private void InitialPawnsDrawing(Player i_Player)
        {
            List<CheckerCell> playerPawn = i_Player.GetPlayerPawnsArray();
            foreach (CheckerCell currentCell in playerPawn)
            {
                this.m_UIBoard[currentCell.CellColumn - 'A', currentCell.CellRow - 'a'].Text = i_Player.Symbol.ToString();
                this.m_UIBoard[currentCell.CellColumn - 'A', currentCell.CellRow - 'a'].Symbol = i_Player.Symbol;
            }
        }

        public void WhenButtonClicked(UICheckersCell i_UICheckersCell)
        {
            bool hasTurn = true;
            bool isIllegalMove = false;

            if (i_UICheckersCell.IsClicked)
            {
                if (this.m_moveToInterpretate.Length == 0)
                {
                    if (i_UICheckersCell.Symbol != this.m_currentPlayer.Symbol && i_UICheckersCell.Symbol != ' ' && i_UICheckersCell.Symbol != this.m_currentPlayer.SpecialSymbol)
                    {
                        i_UICheckersCell.BackColor = Color.White;
                        i_UICheckersCell.IsClicked = false;
                        MessageBox.Show("Not your turn");
                    }
                    else if ((i_UICheckersCell.Symbol == this.m_currentPlayer.Symbol || i_UICheckersCell.Symbol == this.m_currentPlayer.SpecialSymbol) && i_UICheckersCell.Symbol != ' ')
                    {
                        this.m_moveToInterpretate += this.TranslateButtonToString(i_UICheckersCell);
                    }
                    else
                    {
                        i_UICheckersCell.BackColor = Color.White;
                        i_UICheckersCell.IsClicked = false;
                    }
                }
                else
                {
                    this.m_moveToInterpretate += ">" + this.TranslateButtonToString(i_UICheckersCell);
                    CheckersGame.CheckForAvailableMoves(ref this.m_currentPlayer, this.m_GameBoard);
                    this.m_currentMove = CheckersGame.InterpretateStringToMove(this.m_moveToInterpretate, this.m_currentPlayer);
                    if (CheckersGame.isInputMoveLegal(this.m_currentMove, this.m_currentPlayer))
                    {
                        hasTurn = CheckersGame.HandlePlayerTurn(this.m_currentPlayer, this.SecondPlayer(), this.m_GameBoard, this.m_currentMove);
                        this.m_GameBoard.updatePlayerMoveInGameBoard(this.m_currentMove);
                    }
                    else
                    {
                        isIllegalMove = true;
                        MessageBox.Show("Illegal Move!!");
                    }
                    
                    if (!isIllegalMove && !hasTurn)
                    {
                        CheckersGame.CheckForAvailableMoves(ref this.m_currentPlayer, this.m_GameBoard);
                        this.m_currentPlayer.HasEatingMoves = false;
                        this.m_currentPlayer = this.SecondPlayer();
                    }

                    CheckersGame.CheckForAvailableMoves(ref this.m_currentPlayer, this.m_GameBoard);
                    bool endOfMatch = CheckersGame.IsEndOfMatch(this.m_PlayerO, this.m_PlayerX);
                    this.UnClickButtons(this.m_currentMove);
                    this.m_moveToInterpretate = string.Empty;

                    if (this.m_numberOfPlayers == 1 && !hasTurn && !endOfMatch)
                    {
                        this.HandleComputerTurn();
                    }
                }
            }
            else
            {
                this.m_moveToInterpretate = string.Empty;
            }
        }

        private void HandleComputerTurn()
        {
            bool hasTurn = true;
            while (hasTurn)
            {
                CheckersGame.CheckForAvailableMoves(ref this.m_currentPlayer, this.m_GameBoard);
                this.m_currentMove = this.m_currentPlayer.GeneratePlayerMove();
                hasTurn = CheckersGame.HandlePlayerTurn(this.m_currentPlayer, this.SecondPlayer(), this.m_GameBoard, this.m_currentMove);
                this.m_GameBoard.updatePlayerMoveInGameBoard(this.m_currentMove);
            }

            this.m_currentPlayer = this.SecondPlayer();
        }

        public void HandleEndOfMatch(char i_winningSymbol)
        {
            string output = string.Empty;
            DialogResult usersChoice = new DialogResult();
            switch (i_winningSymbol)
            {
                case 'X':
                    output = this.m_PlayerX.Name + " Won!";
                    CheckersGame.UpdateMatchResult(this.m_PlayerO, this.m_PlayerX, i_winningSymbol);
                    break;
                case 'O':
                    output = this.m_PlayerO.Name + " Won!";
                    CheckersGame.UpdateMatchResult(this.m_PlayerO, this.m_PlayerX, i_winningSymbol);
                    break;
                case 'T':
                    output = "Tie!";
                    break;
                default:
                    break;
            }

            output += System.Environment.NewLine + "Another Round?";
            usersChoice = MessageBox.Show(output, "Damka", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            this.DialogResult = usersChoice;
            this.Close();
        }

        private void UnClickButtons(CheckersMove i_CheckersMove)
        {
            this.m_UIBoard[i_CheckersMove.fromCell.CellColumn - 'A', i_CheckersMove.fromCell.CellRow - 'a'].IsClicked = false;
            this.m_UIBoard[i_CheckersMove.toCell.CellColumn - 'A', i_CheckersMove.toCell.CellRow - 'a'].IsClicked = false;
            this.m_UIBoard[i_CheckersMove.fromCell.CellColumn - 'A', i_CheckersMove.fromCell.CellRow - 'a'].BackColor = Color.White;
            this.m_UIBoard[i_CheckersMove.toCell.CellColumn - 'A', i_CheckersMove.toCell.CellRow - 'a'].BackColor = Color.White;
        }

        public void UpdateUIBoardOnClick(int i_Column, int i_Row, char i_Symbol)
        {
            this.m_UIBoard[i_Column, i_Row].Text = i_Symbol.ToString();
            this.m_UIBoard[i_Column, i_Row].Symbol = i_Symbol;
            this.m_UIBoard[i_Column, i_Row].BackColor = Color.White;
        }

        private Player SecondPlayer()
        {
            if (this.m_currentPlayer.Symbol == 'X')
            {
                return this.m_PlayerO;
            }
            else
            {
                return this.m_PlayerX;
            }
        }

        private string TranslateButtonToString(UICheckersCell i_UICheckersCell)
        {
            string stringToReturn;
            stringToReturn = i_UICheckersCell.Column.ToString() + i_UICheckersCell.Row.ToString();
            return stringToReturn;
        }
    }
}